package com.woniuxy.renters.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.woniuxy.core.exception.accountException.AccountException;
import com.woniuxy.core.exception.accountException.AccountExceptionCode;
import com.woniuxy.core.staticCode.UserCode;
import com.woniuxy.core.util.RedisKeyUtil;
import com.woniuxy.core.util.RedisUtil;
import com.woniuxy.core.util.SMSUtil;
import com.woniuxy.renters.dao.RentersAccount;
import com.woniuxy.renters.dao.RentersInfo;
import com.woniuxy.renters.mapper.RentersAccountMapper;
import com.woniuxy.renters.mapper.RentersInfoMapper;
import com.woniuxy.renters.model.dto.RentersLoginDto;
import com.woniuxy.renters.model.form.AddrentersForm;
import com.woniuxy.renters.model.form.Renterslogin1Form;
import com.woniuxy.renters.model.form.RentersloginForm;
import com.woniuxy.renters.model.param.UpdatepassParam;
import com.woniuxy.renters.service.RentersAccountService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author 凌玉春
 * @since 2024年01月15日
 */
@Service
public class RentersAccountServiceImpl extends ServiceImpl<RentersAccountMapper, RentersAccount> implements RentersAccountService {
    @Resource
    private RedisUtil redisUtil;
    @Autowired
    private RedissonClient redissonClient;
    @Autowired
    private RentersAccountMapper rentersAccountMapper;
    @Autowired
    private RentersInfoMapper rentersInfoMapper;

    @Resource
    private SMSUtil smsUtil;

    @Override
    public void test() {
        System.out.println("测试成功");
        return;
    }

    @Override
    public void rentersRegister(AddrentersForm form) throws Exception {

        QueryWrapper<RentersAccount> wrapper = new QueryWrapper<>();
        wrapper.eq("renters_account",form.getRentersAccount());
        RentersAccount rentersAccount1 = rentersAccountMapper.selectOne(wrapper);
        if (rentersAccount1!=null){
            throw new AccountException(AccountExceptionCode.ACCIUNT_USERUSE);
        }

        QueryWrapper<RentersAccount> Wrapper1 = new QueryWrapper<>();
        Wrapper1.eq("renters_phone",form.getRentersPhone());
        RentersAccount rentersAccount2 = rentersAccountMapper.selectOne(Wrapper1);
        if (rentersAccount2!=null){
            throw new AccountException(AccountExceptionCode.PHONE_OCCUPY);
        }

        //创建锁
        RLock lock1 = redissonClient.getFairLock(RedisKeyUtil.lockPhone(form.getRentersPhone()));
        RLock lock2 = redissonClient.getFairLock(RedisKeyUtil.lockUserName(form.getRentersAccount()));
        RLock Lock = redissonClient.getMultiLock(lock1, lock2);
        String total = redisUtil.get(RedisKeyUtil.erroTotal(form.getRentersPhone()));
        if (total != null && Integer.parseInt(total) > 5) {
            //删除验证码 和 验证码错误计数器
            redisUtil.del1(RedisKeyUtil.registerCodeKey(form.getRentersPhone()));
            redisUtil.del1(RedisKeyUtil.erroTotal(form.getRentersPhone()));
            throw new AccountException(AccountExceptionCode.CODE_MAX);
        }
        //取出实际的验证码
        String code = redisUtil.get(RedisKeyUtil.registerCodeKey(form.getRentersPhone()));
        ///ada
        String code1 = form.getCode();
        if (code1 == null || code1 == "") {
            throw new AccountException(AccountExceptionCode.CODE_NOT_NULL);
        }
        if (!form.getCode().equals(code)) {
            if (!redisUtil.exists(RedisKeyUtil.erroTotal(form.getRentersPhone()))) {
                redisUtil.set(RedisKeyUtil.erroTotal(form.getRentersPhone()), "1", 5 * 60);
            } else {
                redisUtil.incr(RedisKeyUtil.erroTotal(form.getRentersPhone()));
            }
            throw new AccountException(AccountExceptionCode.VERIFICATION_CODE_ERROR);
        }
        boolean b = Lock.tryLock(20, TimeUnit.SECONDS);
        if (b) {
            try {
                RentersAccount rentersAccount = BeanUtil.toBean(form, RentersAccount.class);
                rentersAccount.setRenyerState(UserCode.USER_CODE.getCode());

                rentersAccountMapper.insert(rentersAccount);
                //得到用户id
                Integer userId = rentersAccount.getRentersId();
                RentersInfo rentersInfo = BeanUtil.toBean(rentersAccount, RentersInfo.class);
                rentersInfo.setRentersAccountId(userId);
                rentersInfo.setRentersInfoPhone(form.getRentersPhone());
                //设置默认为1 表示未实名认证
                rentersInfo.setRentersInfoStatus(1);
                rentersInfoMapper.insert(rentersInfo);
                //删除发送的验证码
                redisUtil.del1(RedisKeyUtil.registerCodeKey(form.getRentersPhone()));
            } finally {
                Lock.unlock();
            }
        } else {
            throw new AccountException(AccountExceptionCode.SERVER_BUSY);
        }
    }

    @Override
    public void rentersSend(String rentersPhone) throws Exception {
        if (redisUtil.exists(RedisKeyUtil.sendRegisterCodeInMinute(rentersPhone))) {
            throw new AccountException(AccountExceptionCode.DONT_ALWAYS_BUSY);
        }
        String total = redisUtil.get(RedisKeyUtil.codeTotalInHour(rentersPhone));
        if (total != null && Integer.parseInt(total) >= 5) {
            throw new AccountException(AccountExceptionCode.TIMEOUT);
        }

        QueryWrapper<RentersAccount> wrapper = new QueryWrapper<>();
        wrapper.eq("renters_phone", rentersPhone);
        RentersAccount rentersAccount = rentersAccountMapper.selectOne(wrapper);
        if (rentersAccount != null) {
            throw new AccountException(AccountExceptionCode.PHONE_OCCUPY);
        }
        String code = smsUtil.send(rentersPhone);

        redisUtil.set(RedisKeyUtil.registerCodeKey(rentersPhone), code, 5 * 60);
        redisUtil.set(RedisKeyUtil.sendRegisterCodeInMinute(rentersPhone), "0", 60);
        if (!redisUtil.exists(RedisKeyUtil.codeTotalInHour(rentersPhone))) {
            redisUtil.set(RedisKeyUtil.codeTotalInHour(rentersPhone), "1", 60 * 60);
        } else {
            redisUtil.incr(RedisKeyUtil.codeTotalInHour(rentersPhone));
        }
    }

    @Override
    public void rentersSend1(String rentersInfoTel) throws Exception {
        if (redisUtil.exists(RedisKeyUtil.sendRegisterCodeInMinute(rentersInfoTel))) {
            throw new AccountException(AccountExceptionCode.DONT_ALWAYS_BUSY);
        }
        String total = redisUtil.get(RedisKeyUtil.codeTotalInHour(rentersInfoTel));
        if (total != null && Integer.parseInt(total) >= 5) {
            throw new AccountException(AccountExceptionCode.TIMEOUT);
        }

        String code = smsUtil.send(rentersInfoTel);
//        验证码存储在 Redis 中，并设置过期时间为 5 分钟。
        redisUtil.set(RedisKeyUtil.registerCodeKey(rentersInfoTel), code, 5 * 60);
//        设置过期时间为 60 秒。
        redisUtil.set(RedisKeyUtil.sendRegisterCodeInMinute(rentersInfoTel), "0", 60);
        if (!redisUtil.exists(RedisKeyUtil.codeTotalInHour(rentersInfoTel))) {
            redisUtil.set(RedisKeyUtil.codeTotalInHour(rentersInfoTel), "1", 60 * 60);
        } else {
            redisUtil.incr(RedisKeyUtil.codeTotalInHour(rentersInfoTel));
        }
    }

    @Override
    public RentersLoginDto renterslogin(RentersloginForm rf) {
        if(rf.getRentersAccount()==null){
            throw new AccountException(AccountExceptionCode.USERACCOUNT_NOT_NULL);
        }
        if(rf.getRentersPass()==null){
            throw new AccountException(AccountExceptionCode.USERPASS_NOT_NULL);
        }
        QueryWrapper<RentersAccount> wrapper = new QueryWrapper<>();
        wrapper.eq("renters_account",rf.getRentersAccount());
        wrapper.eq("renters_pass",rf.getRentersPass());
        RentersAccount rentersAccount = rentersAccountMapper.selectOne(wrapper);
        if(rentersAccount==null){
            throw new AccountException(AccountExceptionCode.ERROR_ACCPSS);
        }
        return BeanUtil.toBean(rentersAccount,RentersLoginDto.class);
    }

    @Override
    public RentersLoginDto renterslogin1(Renterslogin1Form uf) throws Exception {
        //创建锁
        RLock lock1 = redissonClient.getFairLock(RedisKeyUtil.lockPhone(uf.getRentersInfoTel()));
        RLock Lock = redissonClient.getMultiLock(lock1);
        String total = redisUtil.get(RedisKeyUtil.erroTotal(uf.getRentersInfoTel()));
        if (total != null && Integer.parseInt(total) > 5) {
            //删除验证码 和 验证码错误计数器
            redisUtil.del1(RedisKeyUtil.registerCodeKey(uf.getRentersInfoTel()));
            redisUtil.del1(RedisKeyUtil.erroTotal(uf.getRentersInfoTel()));
            throw new AccountException(AccountExceptionCode.CODE_MAX);
        }
        //取出实际的验证码
        String code = redisUtil.get(RedisKeyUtil.registerCodeKey(uf.getRentersInfoTel()));

        String code1 = uf.getCode();
        if (code1 == null || code1.equals("")) {
            throw new AccountException(AccountExceptionCode.CODE_NOT_NULL);
        }
        if (!uf.getCode().equals(code)) {
            if (!redisUtil.exists(RedisKeyUtil.erroTotal(uf.getRentersInfoTel()))) {
                redisUtil.set(RedisKeyUtil.erroTotal(uf.getRentersInfoTel()), "1", 5 * 60);
            } else {
                redisUtil.incr(RedisKeyUtil.erroTotal(uf.getRentersInfoTel()));
            }
            throw new AccountException(AccountExceptionCode.VERIFICATION_CODE_ERROR);
        }
        boolean b = Lock.tryLock(20, TimeUnit.SECONDS);

        if (b) {
            try {
                QueryWrapper<RentersAccount> wrapper = new QueryWrapper<>();
                wrapper.eq("renters_phone", uf.getRentersInfoTel());
                RentersAccount rentersAccount = rentersAccountMapper.selectOne(wrapper);
                if (rentersAccount == null) {
                    //删除发送的验证码
                    redisUtil.del1(RedisKeyUtil.registerCodeKey(uf.getRentersInfoTel()));
                    throw new AccountException(AccountExceptionCode.PHONE_NOT_REGISTER);
                }
            }
            finally
            {
                Lock.unlock();
            }
        }
        else
        {
            throw new AccountException(AccountExceptionCode.SERVER_BUSY);
        }
        QueryWrapper<RentersAccount> wrapper = new QueryWrapper<>();
        wrapper.eq("renters_phone", uf.getRentersInfoTel());
        RentersAccount rentersAccount = rentersAccountMapper.selectOne(wrapper);

        return BeanUtil.toBean(rentersAccount,RentersLoginDto.class);
    }

    @Override
    public void updatePassword(UpdatepassParam param) {
        RentersAccount rentersAccount = rentersAccountMapper.selectById(param.getUserId());
        //用户不存在
        if (rentersAccount==null){
            throw new AccountException(AccountExceptionCode.NO_USER);
        }
        //判断旧密码是否正确
        if (!rentersAccount.getRentersPass().equals(param.getOldPass())){
            throw  new AccountException(AccountExceptionCode.PASS_ERROR);
        }
        //修改密码
        rentersAccount.setRentersPass(param.getNewPass());
        rentersAccountMapper.updateById(rentersAccount);
    }
}
